package MetroMessenger;

import java.net.InetAddress;
import java.net.Socket;
import java.io.IOException;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

import javax.swing.JOptionPane;

public class SocketMessageManager implements MessageManager
{
   private Socket clientSocket; 
   private String serverAddress;
   private PacketReceiver receiver;
   private boolean connected = false;
   private ExecutorService serverExecutor; 
   
   public SocketMessageManager( String address )
   {
      serverAddress = address;
      serverExecutor = Executors.newCachedThreadPool();
   }
   public void connect( MessageListener listener ) 
   {
      if ( connected )
         return; 

      try 
      {
         clientSocket = new Socket( InetAddress.getByName( serverAddress ), SocketMessengerConstants.SERVER_PORT );
         receiver = new PacketReceiver( listener );
         serverExecutor.execute( receiver ); 
         connected = true;
      } 
      catch ( IOException ioException ) 
      {
         JOptionPane.showMessageDialog(null,ioException.getMessage()+"\n\n Contact Administrator","Server Problem",JOptionPane.ERROR_MESSAGE);
      } 
   }
   public void disconnect( MessageListener listener ,String user) 
   {
      if ( !connected )
         return; 
      try 
      {     
         Runnable disconnecter = new MessageSender( clientSocket,user+SocketMessengerConstants.MESSAGE_SEPARATOR + SocketMessengerConstants.DISCONNECT_STRING);         
         Future disconnecting = serverExecutor.submit( disconnecter );         
         disconnecting.get(); 
         receiver.stopListening(); 
         clientSocket.close(); 
      } 
      catch ( ExecutionException exception ) 
      {
         exception.printStackTrace();
      } 
      catch ( InterruptedException exception ) 
      {
         exception.printStackTrace();
      } 
      catch ( IOException ioException ) 
      {
         ioException.printStackTrace();
      } 
     
      connected = false; 
   }
   
   public void sendMessage(String message ) 
   {
      if ( !connected )
         return;
      serverExecutor.execute( new MessageSender( clientSocket, message) );
   }
}